Skip to content

Enable Central Package Management with transitive pinning - #20084

Merged
T-Gro merged 27 commits into
mainfrom
t-gro-enable-cpm-transitive-pinning
Aug 4, 2026
Merged

Enable Central Package Management with transitive pinning#20084
T-Gro merged 27 commits into
mainfrom
t-gro-enable-cpm-transitive-pinning

Conversation

@T-Gro

@T-Gro T-Gro commented Jul 24, 2026

Copy link
Copy Markdown
Member

Turn on NuGet Central Package Management with transitive pinning across the
repo: package versions now come from a single central list (eng/Packages.props),
and vulnerable transitive dependencies such as System.Security.Cryptography.Xml
are pinned repo-wide.

This unblocks removing the -warnNotAsErrors NuGet Audit workaround for fsharp
in the dotnet/dotnet VMR.

T-Gro and others added 19 commits July 22, 2026 21:25
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Uses ImportDirectoryPackagesProps=false (reliable subtree opt-out; a
Directory.Build.props-level ManagePackageVersionsCentrally=false is
overridden by the later root Directory.Packages.props import).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@(MIBCPackage) carries Version metadata (used by CopyMIBC); an item
->'%(Identity)' transform does NOT drop metadata, so list the five
packages explicitly without a version. Versions come from the central
eng/Packages.props entries.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Excludes opt-out subtrees, eng/common (Arcade-managed, not under CPM),
and src/FSharp.Build/Microsoft.FSharp.NetSdk.props (ships to user projects).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
These LSP/VS-integration projects pin older VS 17.x versions than the
central 18.x baseline; VersionOverride preserves their exact versions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
MSBuild 18.10 pulls System.Security.Cryptography.Xml >= 10.0.9 transitively and
OpenTelemetry pulls Microsoft.Extensions.DependencyInjection >= 10.0.0; raise the
central pins to those floors so transitive pinning does not downgrade them.
Source-build keeps the live S.S.C.Xml via a non-source-build-gated override, and
FSharp.Compiler.LanguageServer (net8) keeps DI 8.0.0 via VersionOverride.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ion.Metadata

MSBuild 18.10 also pulls these dotnet/runtime packages >= 10.0.9 transitively; raise
their central pins to the same 10.0.9 floor (non-source-build only, source-build keeps
the live versions).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
VisualFSharp.slnx surfaced two more CPM issues:
- MIBC packages (added to every project by Directory.Build.targets) lacked a
  version in CPM-opt-out subtrees (setup/Swix) -> NU1015. Split the ItemGroup so
  opt-out projects carry @(MIBCPackage) Version metadata while CPM projects stay
  identity-only.
- The VS SDK (18.9.496, via Microsoft.CodeAnalysis.ExternalAccess.FSharp) pulls
  several VS packages higher than the declared 18.0.x pins; under transitive
  pinning these downgraded. Raised the editor group to 18.9.123 and pinned
  Shell.Design/Package.LanguageService.15.0 (18.9.493), Designer.Interfaces
  (18.9.438), Nullable (1.3.1) and LanguageServer.Protocol (17.13.9) to the
  versions already resolved transitively.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
NoWarn set in Directory.Packages.props is discarded by projects that reset NoWarn
in their body (e.g. tests set <NoWarn>3186</NoWarn>). Move the NU1507 suppression to
Directory.Build.targets, which is imported after project bodies, so it applies to
every CPM project.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The MSBuild 18.10 toolchain (fsc/fsi and FSharp.Build.UnitTests) pulls
System.Collections.Immutable / System.Reflection.Metadata / System.Security.Cryptography.Xml
transitively at >= 10.0.9, so the CPM transitive pin must meet that floor. Introduce
dedicated System*CentralVersion properties for the central list instead of overriding the
darc-flowed System*Version properties, which must stay authoritative for source-build and for
FSharp.Compiler.Service's shipped nuspec dependency metadata (FCS does not pull MSBuild). The
floor only raises when darc is below 10.0.9; once darc flows a higher version, darc wins.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…t subtrees

EndToEndBuildTests and other subtrees set ImportDirectoryPackagesProps=false and are not under
CPM, so the central list does not apply and the versionless test PackageReferences would restore
nothing silently. Add an inline-versioned Update ItemGroup guarded on ImportDirectoryPackagesProps=false,
sourced from the same XunitVersion/etc. properties those subtrees already define.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Remove three now-dead 'PackageReference Update=Microsoft.VSSDK.BuildTools' lines whose only
  purpose was the Version metadata the CPM strip removed; transitive pinning supplies the version.
- Restore the Version attributes on the commented-out OpenTelemetry block the strip wrongly touched.
- Drop trailing whitespace left on a stripped PackageReference in FSharp.Editor.fsproj.
- Document why the LanguageServer.Protocol central pin is 17.13.9 and why MIBC identities are listed
  literally under CPM.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- eng/Versions.props: group the two shell properties still on the package-group version above the
  'pinned to 18.9.x' comment so that comment sits only over the three literally pinned properties
  (value-preserving reorder).
- tests/AheadOfTime/Directory.Build.props: fold the opt-out property into the adjacent PropertyGroup
  to match every other opt-out file.
- FSharp.Compiler.LanguageServer.fsproj: note why the DI VersionOverride stays on 8.0.0.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
FSCoreProductVersion, MicrosoftVisualStudioInteropVersion,
MicrosoftVisualStudioImagingInterop140DesignTimeVersion, and the three
MicroBuild* setup versions had zero references repo-wide (grep-verified).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Manually-pinned, single-use package versions previously defined as
properties in eng/Versions.props solely to be referenced once by a
<PackageVersion> in eng/Packages.props are now inlined as literals at the
pin, removing the Versions.props<->Packages.props duality. Load-bearing
rationale comments move with them. Genuinely shared version groups
(VisualStudioEditorPackagesVersion, the System.* central floors, Xunit/
TestPlatform, FSharpCore*), darc/Maestro-flowed versions, and the
Arcade-read MicrosoftVSSDKBuildToolsVersion stay as properties.

Also drops the dead Dotnet.ProjInfo central pin (no remaining consumer).
Net: eng/Versions.props shrinks 202 -> 138 lines. Restore/build unchanged
(inlined values are byte-identical to MSBuild's prior resolution).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
With CentralPackageTransitivePinningEnabled, packages consumed only
transitively no longer need direct <PackageReference>s:
- FSharp.Build: System.Security.Cryptography.Xml (dead historic override),
  System.Memory, System.Runtime.CompilerServices.Unsafe
- FSharp.DependencyManager.Nuget: System.Reflection.Emit/Metadata/Unsafe
  (the ns2.0 plugin uses host-side System.Reflection, never emits IL)
- fsc.targets: net472 System.Memory/Unsafe ItemGroup
- FSharp.Compiler.Service.Tests: Newtonsoft.Json (redundant; transitive via
  FSharp.Test.Utilities and centrally pinned)

System.Security.Cryptography.Xml now has zero direct references repo-wide;
its central pin alone holds the secure version transitively.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…omment, extract test predicate

Round-1 of the cross-model compaction vote (unanimous 3/3 on each):
- Single-source the 10.0.9 dotnet/runtime transitive floor into
  $(SystemRuntimeCentralFloorVersion) (was 6 literal occurrences).
- Bind Microsoft.VisualStudio.Platform.VSEditor to the existing
  $(VisualStudioEditorPackagesVersion) group (removes a magic 18.9.123 literal).
- De-duplicate the NU1109 editor-pin rationale comment (keep it in eng/Packages.props).
- Extract the 4x-repeated test-runner name condition into $(_IsTestRunnerProject).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…policy comment

Round-2 of the cross-model compaction vote:
- Delete the dead `UnitTestType == 'xunit'` ItemGroup in Directory.Build.targets:
  nothing ever sets UnitTestType to 'xunit' (only 'none'), and xunit.v3.mtp-v2 is
  already added to every test-runner project by tests/Directory.Build.props. (3/3)
- Trim the inline-vs-property policy parenthetical in eng/Versions.props; the canonical
  statement already lives in the eng/Packages.props header. (2/3)

Contested proposals that FAILED the vote (kept as-is): folding XunitRunnerConsoleVersion
(genuine 3x use, coincidental value), removing per-file CPM opt-out comments, removing the
pre-existing commented OpenTelemetry block, removing the EndToEnd version fallbacks (proven
load-bearing in Arcade builds), hoisting VersionPrefix in the product-version block.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The xunit.v3.* family (assert/common/extensibility.core/mtp-v2/runner.console)
ships in lockstep; runner.console had a separate $(XunitRunnerConsoleVersion)
property duplicating $(XunitVersion) (both 3.2.2) with no active deviation.
Point the runner.console pin (and the EndToEnd opt-out override) at
$(XunitVersion) and delete the redundant property + its EndToEnd fallback.
Resolved version unchanged (3.2.2); restore + ./build.sh -c Release clean.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@T-Gro
T-Gro requested a review from a team as a code owner July 24, 2026 09:21
@T-Gro T-Gro added the NO_RELEASE_NOTES Label for pull requests which signals, that user opted-out of providing release notes label Jul 24, 2026
@T-Gro
T-Gro requested a review from abonie July 24, 2026 09:21
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

⚠️ Release notes required, but author opted out

Warning

Author opted out of release notes, check is disabled for this pull request.
cc @dotnet/fsharp-team-msft

Source-build also builds live Microsoft.Build.Tasks.Core 18.10, which
pulls System.Security.Cryptography.Xml transitively at >= 10.0.9. The
floor was gated to non-source-build, so the central pin stayed at the
darc 10.0.8 and CPM transitive pinning raised NU1109 (downgrade
10.0.9 -> 10.0.8) in the Source-Build (Managed) jobs. Drop the gate so
the max(darc, 10.0.9) floor applies in every build mode. The darc-flowed
$(System*Version) properties are untouched, so FCS's shipped nuspec
metadata still uses the darc version.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added the AI-Tooling-Check-Bypassed Tooling check: non-fork PR, not diff-analyzed label Jul 24, 2026
T-Gro and others added 3 commits July 24, 2026 12:13
tests/FSharp.Test.Utilities/TestFramework.fs parses eng/Versions.props by
property name at module-init to locate csc/vbc/ilasm/ildasm in the NuGet
cache. The version-literal diet had inlined these into eng/Packages.props
and deleted the MicrosoftNetCompilersVersion / MicrosoftNETCoreILAsmVersion
/ MicrosoftNETCoreILDAsmVersion properties, so the assembly fixture threw
'Property not found in Versions.props' in its constructor and every test in
the assembly failed at 0ms (Linux/macOS test jobs). Keep them as properties
and have eng/Packages.props reference them, so there is still a single
source and no duplicate literal.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Arcade's VisualStudio.targets injects Microsoft.VSSDK.BuildTools as an
implicit PackageReference (IsImplicitlyDefined=true,
Version=$(MicrosoftVSSDKBuildToolsVersion)) into VSIX/pkgdef projects. Under
CPM an implicitly-defined reference must carry its own version and cannot
have a central PackageVersion, so the central entry raised NU1009 across
every Windows job that builds vsintegration (VisualFSharp.slnx). Remove the
central PackageVersion; Arcade versions it from the property we keep.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fixes CS0433 (ambiguous S/IComponentModel) in FSharp.Editor.IntegrationTests.
Under transitive pinning it pulled Shell.Framework 18.x while ComponentModelHost
stayed at 17.x; the 17.x/18.x split made the type-forward ambiguous. Pin it to
the VS SDK 18.9.496 set so the types resolve to a single assembly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…rver

Fixes MSB3277 (StreamJsonRpc 2.25 vs 2.26 conflict). The override held 2.25.29
while the transitively-pinned Proxy used central 2.26.5; the two disagreed. Both
now use central 2.26.5 (identical Threading.Only >= 17.14.15 floor, so no NU1109).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added ⚠️ Affects-Build-Infra Tooling check: PR touches build infrastructure ⚠️ Affects-Restore Tooling check: PR touches NuGet packages or feeds labels Jul 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Tooling Safety Check — Affects-Build-Infra, Affects-Restore
Affects-Build-Infra: adds Directory.Packages.props, Directory.Build.targets, modifies eng/Packages.props and multiple .fsproj files
Affects-Restore: introduces Central Package Management changing how all packages resolve

Generated by PR Tooling Safety Check · opus46 11.6M ·

@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling Jul 28, 2026
@T-Gro
T-Gro enabled auto-merge (squash) August 3, 2026 18:34
T-Gro and others added 3 commits August 3, 2026 20:52
Resolved eng/Versions.props: kept the diet's CentralVersion/floor machinery and
restructured tool-version block; took main's MicrosoftTestPlatformVersion bump
17.14.1 -> 18.0.1 and its net472 facade override properties (SystemNetHttp /
SystemTextRegularExpressions). fsproj/props union-merged (built-in git union
driver restored — a stale global merge.union.driver had been silently dropping
main's additions).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
PR #20058 added per-project package overrides to work around the LACK of
Central Package Management. Now that CPM + transitive pinning is enabled here,
those overrides are redundant AND invalid (a PackageReference under CPM cannot
carry Version=, so they trip NU1008). This removes/consolidates them:

- fsc/fsi/FSharp.Build.UnitTests: drop the 3 identical netcore-only
  System.Security.Cryptography.Xml overrides. It is centrally pinned
  (10.0.10) and transitive pinning now raises the Microsoft.Build.Tasks.Core
  transitive on netcore automatically (verified via restore); net472 is
  untouched (crypto.xml not in its graph -> no ValueTuple conflict).
- LanguageServer: drop the per-project MessagePack 2.5.302 override; pin it
  centrally instead so transitive pinning patches it wherever StreamJsonRpc is
  used (LanguageServer AND the CLASP.Framework.Proxy), not just one project.
- Test.Utilities: keep the net472-only System.Net.Http/System.Text.RegularExpressions
  facade overrides but as local VersionOverride (no global eng/Versions.props
  properties), keeping the deviation minimal and scoped.

Also resolves union-merge duplicate PackageReference blocks introduced by the
merge from main in Microsoft.FSharp.Compiler, LanguageServer, and Test.Utilities.

Verified by clean bootstrap ./build.sh -c Debug (0 warnings, 0 errors) and by
inspecting restored versions: crypto.xml 10.0.10 (fsc), MessagePack 2.5.302
(LanguageServer + Proxy), StreamJsonRpc 2.26.5.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Resolve union-merge duplicates in vsintegration fsprojs and
Directory.Build.targets by keeping CPM-style refs (no inline Version)
and renaming the ExternalAccess package/property to
Microsoft.VisualStudio.LanguageServices.ExternalAccess
(MicrosoftVisualStudioLanguageServicesExternalAccessVersion).
Central pin in eng/Packages.props renamed accordingly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@T-Gro
T-Gro merged commit 36ce348 into main Aug 4, 2026
49 checks passed
T-Gro pushed a commit that referenced this pull request Aug 4, 2026
…30-4e71-bcc3-2d3f59911b20

Resolve conflict from Central Package Management migration (#20084): keep the single CPM-compliant Microsoft.DotNet.NuGetRepack.Tasks PackageReference (no Version, PrivateAssets=all) and retain the Arcade 10 NuGetRepack UsingTask workaround needed by the downgraded Arcade SDK.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
T-Gro pushed a commit that referenced this pull request Aug 4, 2026
…#19993) into darc-main-bd030f95

Resolve eng/Versions.props conflict by adopting origin/main's Central Package Management structure (VS package versions live in eng/Packages.props). Bump the four VS pins Roslyn 5.11.0 requires higher than main's 5.10.0 baseline: Microsoft.VisualStudio.Threading 18.7.23, Microsoft.VisualStudio.RpcContracts 18.9.918, Microsoft.ServiceHub.Framework 4.10.147, StreamJsonRpc 2.26.10, and raise the shared editor pin VisualStudioEditorPackagesVersion to 18.9.179 (Roslyn 5.11.0 pulls the VS editor packages transitively at 18.9.179 -> NU1109 otherwise). Take origin/main's CPM form of Framework.Proxy.csproj (drop redundant Version-bearing PackageReferences superseded by central pins).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
T-Gro pushed a commit that referenced this pull request Aug 4, 2026
The merge of the arcade update with the Central Package Management PR (#20084)
left duplicated PackageReference entries in the runtime-dependencies ItemGroup,
including an unterminated <PackageReference> tag that caused MSB4025
(project could not be loaded), failing every CI build job. Remove the stale
versioned entries, keeping only the versionless CPM-style references.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
T-Gro pushed a commit that referenced this pull request Aug 4, 2026
…M merge

The merge that pulled the Central Package Management change (#20084) into this
release/dev18.0-based branch left, in 12 project files, a duplicated block of the
old versioned PackageReference entries above the new versionless CPM entries.
NuGet restore failed with NU1504 (Duplicate 'PackageReference' items) across
FSharp.Test.Utilities and the vsintegration projects, breaking every CI job.
FSharpSuite.Tests.fsproj additionally had a duplicate <OutputType>.

Restore all affected project files to their origin/main (CPM baseline) state,
which drops exactly the leftover duplicates and nothing else.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
T-Gro added a commit that referenced this pull request Aug 5, 2026
* Avoid leaking a MeterListener per Cache in DEBUG builds (#19995)

* Avoid leaking a MeterListener per Cache in DEBUG builds

In DEBUG builds, every Cache instance created a CacheMetrics.CacheMetricsListener,
which starts a System.Diagnostics.Metrics.MeterListener registered in the
process-global metrics registry. These were never disposed, so they accumulated for
the lifetime of the process. Because every cache hit/miss/add publishes a measurement
to all registered listeners, the per-operation cost grew linearly with the number of
leaked listeners, so workloads that create many caches (for example repeated
ParseAndCheckProject / per-file checks) slowed down steadily.

Track the per-cache totals used by DebugDisplay directly, incrementing a small Stats
object alongside the existing global Meter counters, instead of via a per-cache
MeterListener. No listener is created, so nothing leaks, and DebugDisplay still works.
The now-unused CacheMetrics.Hit/Miss/Add/Update/Eviction/EvictionFail helpers are
replaced by a single recordMetric helper.

* Address review: drop per-cache CacheMetricsListener and cacheId tag

- Remove the CacheMetrics.CacheMetricsListener type. Its only per-cache use
  was the #if DEBUG debugListener each Cache created and never disposed, which
  was the leak this PR set out to fix. (majocha)
- Drop the per-instance cacheId tag (and nextCacheId). Measurements now carry
  only the cache name, shrinking the payload published to any connected
  exporter and removing the per-instance filtering that was cacheId's only
  purpose. (majocha)
- DebugDisplay and the cache tests read the existing name-aggregated stats via
  CacheMetrics.getTotalsByName / getRatioByName, populated by the single
  process-wide ListenToAll listener. No per-cache listener is created and no
  per-operation cost is added in any configuration, so there is no DEBUG-only
  overhead left to gate behind a separate directive. (T-Gro)
- Overload-cache tests enable ListenToAll and snapshot totals before/after to
  stay scoped to their own compilation; FSharpChecker
  .CreateOverloadCacheMetricsListener is removed.

* Update public SurfaceArea baseline after removing CacheMetricsListener

CacheMetricsListener was a public type, so dropping it changes the recorded
public surface. Remove its 10 entries from
FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl; the SurfaceArea test
now passes. Also note the single-listener assumption the cache metric tests
rely on.

* Apply fantomas formatting to Caches.fs

* Document why OverloadCacheTests is not parallelizable (global cache metrics state)

---------

Co-authored-by: Tomas Grosup <Tomas.Grosup@gmail.com>

* Bump FCSMinorVersion to 13 (keep main above 10.0.4xx servicing 43.12.400) (#20045)

* Update dependencies from https://github.com/dotnet/msbuild build 20260708.3 (#20048)

On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-preview-26357-08 -> To Version 18.10.0-preview-26358-03

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>

* Update dependencies from https://github.com/dotnet/roslyn build 20260708.9 (#20049)

On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26357.6 -> To Version 5.10.0-1.26358.9

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>

* Add ResetCompilerGeneratedNameState to compiler-generated name generators (#20017)

Compiler-generated occurrence names (name@line-N) are allocated from process-wide
counters on CompilerGlobalState that accumulate across compilations. When a warm
checker re-emits the same project in-process, an unchanged closure therefore gets a
different occurrence suffix than the previous emit, so consumers that align generated
names across compilations (Edit-and-Continue delta emission, #19941)
cannot match them.

Add an internal ResetCompilerGeneratedNameState to NiceNameGenerator (clears the
per-(name, file) occurrence counters), StableNiceNameGenerator (clears the cached
stable names and the inner counters), and an aggregate on CompilerGlobalState that
resets all three generators, restoring the fresh-process name layout. Callers must
ensure no compilation is concurrently generating names.

No in-tree caller yet; the consumer is the hot reload emit path in #19941.
Covered by unit tests proving drift without reset, exact replay after reset, and that
the stable-name cache itself is cleared.

* Update dependencies from https://github.com/dotnet/msbuild build 20260709.10 (#20051)

On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-preview-26358-03 -> To Version 18.10.0-1.26359.10

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>

* [main] Update dependencies from dotnet/msbuild (#20055)

* Update dependencies from https://github.com/dotnet/msbuild build 20260710.4
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26360.4

* Update dependencies from https://github.com/dotnet/msbuild build 20260713.4
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26363.4

* Update dependencies from https://github.com/dotnet/msbuild build 20260714.11
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26364.11

* Update dependencies from https://github.com/dotnet/msbuild build 20260715.6
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26365.6

* Update dependencies from https://github.com/dotnet/msbuild build 20260716.8
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26366.8

* Update dependencies from https://github.com/dotnet/msbuild build 20260717.5
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26367.5

* Update dependencies from https://github.com/dotnet/msbuild build 20260719.1
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26369.1

* Update dependencies from https://github.com/dotnet/msbuild build 20260720.18
On relative base path root
Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.10.0-1.26359.10 -> To Version 18.10.0-1.26370.18

---------

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>

* [main] Update dependencies from dotnet/roslyn (#20052)

* Update dependencies from https://github.com/dotnet/roslyn build 20260709.4
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26359.4

* Fix NU1605 package downgrades from Roslyn 5.10.0-1.26359.4 bump

The new Roslyn build adds a net472 dependency on Microsoft.VisualStudio.SDK
18.9.496-Preview and bumps its runtime deps to 10.0.8, causing package
downgrade errors:
- System.Collections.Immutable / System.Reflection.Metadata / System.Composition
  now required >= 10.0.8 (were pinned to 10.0.2)
- VS interops (OLE/Shell/TextManager.Interop) required >= 18.9.438
- Microsoft.VisualStudio.Threading required >= 18.7.19

The three interop packages are decoupled from the shared shell package
version since the VS SDK pins them newer than the other shell packages.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix MSB3277 assembly conflicts from new Roslyn VS SDK 18.9 deps

The new Roslyn Microsoft.CodeAnalysis.ExternalAccess.FSharp (net472) now
depends on Microsoft.VisualStudio.SDK 18.9.496 and its coherent 18.9.x VS
package set, pulling newer transitive assemblies than fsharp's 18.0.x Shell
packages. This caused MSB3277 (assembly version conflicts) across the
vsintegration projects for:
- System.Diagnostics.DiagnosticSource (10.0.2 vs 10.0.8)
- Microsoft.VisualStudio.Validation (17.13 vs 18.7.1)
- StreamJsonRpc (2.23 vs 2.26.5)
- Microsoft.ServiceHub.Framework (4.9 vs 4.10.128)
- Microsoft.VisualStudio.RpcContracts (17.15.25 vs 18.9.453)

Bump DiagnosticSource to 10.0.8 (coherent with the other runtime deps) and
pin the four remaining transitive packages to the exact versions Roslyn
pulls, so all vsintegration projects resolve them coherently.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix runtime VS assembly load failures in legacy VS unit tests

The Roslyn 5.10.0-1.26359.4 bump pulls Microsoft.VisualStudio.SDK 18.9.496 which transitively upgrades the editor assemblies (Microsoft.VisualStudio.Text.*, .Editor) to 18.9.123 and Shell.15.0 to 18.9.x. Two runtime-only breaks remained after the earlier NU1605/MSB3277 build-time fixes, both surfacing as a ReflectionTypeLoadException in the VsMocks MEF catalog that failed all ~1959 legacy VS unit tests:

1. Microsoft.VisualStudio.Platform.VSEditor is not pulled transitively, so it stayed pinned at 18.0.404-preview and its implementation types no longer bind against the newer Text.Internal 18.9.123 interfaces. Pin VSEditor to 18.9.123 to match.

2. Shell.15.0 18.9.x references Microsoft.VisualStudio.SolutionPersistence at runtime without declaring it as a NuGet dependency; deploy it next to the VS unit-test host (scoped to test projects to keep it out of the VSIX).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix flaky AOT CI build: pass -ci to disable UpdateXlfOnBuild

The Build_And_Test_AOT_Windows job runs '.\Build.cmd -pack' without -ci, so ContinuousIntegrationBuild is not set. Arcade then enables UpdateXlfOnBuild, which flakily fails with 'MSB4057: The target UpdateXlf does not exist' on FSharp.Core (the classic_metadata leg failed while the identical compressed_metadata leg passed). Every other CI job builds via CIBuildNoPublish.cmd/cibuild.sh, which pass -ci. Add -ci here for consistency so ContinuousIntegrationBuild=true and UpdateXlfOnBuild stays disabled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update dependencies from https://github.com/dotnet/roslyn build 20260709.5
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26359.5

* Update dependencies from https://github.com/dotnet/roslyn build 20260713.9
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26363.9

* Update dependencies from https://github.com/dotnet/roslyn build 20260714.9
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26364.9

* Update dependencies from https://github.com/dotnet/roslyn build 20260715.2
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26365.2

* Update dependencies from https://github.com/dotnet/roslyn build 20260715.3
On relative base path root
Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.10.0-1.26358.9 -> To Version 5.10.0-1.26365.3

---------

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Localized file check-in by OneLocBuild Task: Build definition ID 499: Build ID 3013177 (#20023)

Co-authored-by: Copilot <copilot@github.com>

* [main] Update dependencies from dotnet/arcade (#20054)

* Update dependencies from https://github.com/dotnet/arcade build 20260708.3
On relative base path root
Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26324.4 -> To Version 10.0.0-beta.26358.3

* Update dependencies from https://github.com/dotnet/arcade build 20260716.3
On relative base path root
Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26324.4 -> To Version 10.0.0-beta.26366.3

* Update dependencies from https://github.com/dotnet/arcade build 20260717.6
On relative base path root
Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26324.4 -> To Version 10.0.0-beta.26367.6

* Re-run CI (flaky infrastructure failures unrelated to Arcade bump)

The two failing jobs on this darc dependency PR were flaky/infra failures,
not caused by the Arcade SDK version bump:
- WindowsCompressedMetadata transparent_compiler_release: FSharp.Compiler.Service.Tests
  host hang hitting the 5m hangdump timeout (createdump MiniDumpWriteDump failure).
- IcedTasks_Test_Debug Regression Test: net9.0-only 'Entry point was not found'
  in the third-party FSharp.Control.TaskSeq DisposeAsync path (passed on net8.0/net10.0).
Both signatures recur on unrelated PRs (e.g. IcedTasks on #19941).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update dependencies from https://github.com/dotnet/arcade build 20260721.2
On relative base path root
Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26324.4 -> To Version 10.0.0-beta.26371.2

---------

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: T-Gro <15220165+T-Gro@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Tests/source context: support multiple carets (#20077)

* Move VS language-service logic tests to FSharp.Compiler.Service.Tests (#20033)

* Move VS language-service logic tests to FSharp.Compiler.Service.Tests

Port completion, quick info, parameter info, go-to-definition, and
diagnostics coverage from the Windows-only VS Salsa suite to the
cross-platform FSharp.Compiler.Service.Tests. The legacy suite keeps only
the tests that genuinely exercise Visual Studio integration.

* Add Roslyn-format EnC CustomDebugInformation codec and portable PDB method CDI emission (#20018)

* Add Roslyn-format EnC CustomDebugInformation codec and portable PDB method CDI emission

Adds an internal AbstractIL module implementing, byte for byte, the three Portable PDB
CustomDebugInformation blob formats Roslyn persists per method for Edit and Continue
(EnC Local Slot Map, EnC Lambda and Closure Map, EnC State Machine State Map), with
serializers, deserializers, a portable PDB read-back helper, and an occurrence-key
packing helper for deterministic syntax-offset slots.

Plumbs an optional methodCustomDebugInfoRows side channel through the IL binary writer
options into the portable PDB generator so a compilation can attach CDI rows to named
methods. Names that do not identify exactly one method row are dropped. All existing
writer call sites pass an empty map, so emitted PDBs are byte-identical to before.

No in-tree caller populates the map yet; the consumer is the F# hot reload work in
#19941, following the same pattern as #20017 (land isolated, test-covered
infrastructure first, wire the feature later).

Tests: blob round-trips, Roslyn golden-byte encodings, cross-validation against
CDI blobs emitted by a real Roslyn compilation, fail-closed occurrence-key packing
(including an int32-overflow regression where a wrapped negative key previously
escaped the bound check), and end-to-end synthetic PDB emission proving correct
MethodDef parenting, zero rows for an empty map, and no rows for absent or
ambiguous names.

* Add stable synthesized-name replay infrastructure for hot reload (#20024)

* Extract stable synthesized-name replay layer

Add internal generated-name normalization and synthesized-name map replay support as a standalone slice. The new map state is side-channel based, all new compiler modules remain internal, and CompilerGlobalState preserves the existing no-map counter path while checking an accessor captured once per compiler state.

Route existing IlxGen generated-name allocations through inert helper wrappers, add pure name-map and normalizer tests, add a normal compilation determinism guard over emitted generated names, and document the extracted seams in P5_REPORT.md.

Verification: built FSharp.Compiler.Service, FSharp.Compiler.Service.Tests, FSharp.Compiler.ComponentTests, and FSharpSuite.Tests in Release; ran the migrated service test classes, the component determinism class, FSharpSuite DeterministicTests, and the FCS SurfaceArea class successfully.

* Fix generated-name scope test in stable names slice

* Validate hot reload generated names before classification

* Format hot reload compiler sources

Verified with the repository-wide Fantomas check.

* Retry CI after Linux runner memory exhaustion

* Make synthesized name snapshots deterministic

* Fix #19457: lift CE constructs from plain let RHS in computation expressions (#19868)

* Fix attribute resolution in recursive module/namespace scopes (#19744)

* Correct StructLayout size emission for data-less struct unions (#19759)

* Report FS3888 for generic attribute type abbreviations instead of FS0193 (#19915)

* Move to .NET 11 (SDK, Arcade, product TargetFramework) (#20080)

Upgrade the repo to build on .NET 11 and target net11.0, plus the
adaptations the SDK/Arcade 11 bump forces.

Core version switch:
- global.json: sdk.version 11.0.100-preview.6.26359.118 with
  rollForward=latestMinor + allowPrerelease (newer local 11.x still wins).
  A 2-part "11.0" is not a valid concrete SDK version, so the muxer fell
  back to $host$ and the end-to-end tests built with the machine net10 SDK
  (NETSDK1045); a concrete version resolves .dotnet's net11 SDK.
  Arcade.Sdk 11.0.0-beta.26369.1.
- eng/TargetFrameworks.props: FSharpNetCoreProductTargetFramework net11.0.
- eng/Version.Details.xml + eng/Version.Details.props: Arcade.Sdk
  11.0.0-beta.26369.1 (+Sha) — the value Maestro flows from dotnet/arcade
  onto the net11 channel, not a hand-picked one.
- eng/Versions.props: MicrosoftTestPlatformVersion 18.0.1 (net11 SDK bundles
  vstest 18.x; Microsoft.TestPlatform.ObjectModel must track that generation).
- eng/common: regenerated to Arcade 11 (26369.1).

Arcade-11 / SDK adaptations:
- Microsoft.FSharp.Compiler.fsproj: NuGetRepack property casing, drop the
  obsolete UsingTask, add no-op PackageReleasePackages override (#19557).
- fsi.fsproj: PublishReadyToRun=false (crossgen2 preview crashes on fsi).
- tests/Directory.Build.props: mark .ComponentTests IsTestProject (excludes
  from SymStore PDB conversion that crashes on large test assemblies).
- FSharp.DependencyManager.ProjectFile.fs: resolve framework-provided
  assemblies (Microsoft.Extensions.* now in the shared framework) for
  FSI #r "nuget:"; RestoreEnablePackagePruning=false.
- regression-test-jobs.yml: install the compiler SDK into the TestRepo.

net11 test-behavior:
- EditorTests.fs: RegexOptions.AnyNewLine (2048) under NET11_0_OR_GREATER.
- CompilerAssert.fs: derive runtimeconfig runtime version from
  FrameworkDescription + rollForward LatestMinor (preview is semver-lower).
- ILChecker.fs: normalize System.Linq assembly extern (version-independent).
- DependencyManagerInteractiveTests.fs: on net11 Microsoft.Extensions.* are
  shared-framework, so #r "nuget:" resolves the ref-pack path and one root.
- ilverify.ps1: map versioned netN.0 baselines to generic netcoreapp;
  rename the two FSharp.Compiler.Service baselines accordingly.
- EndToEndBuildTests: MicrosoftTestPlatformVersion 18.0.1.

Validated: ./build.sh -c Release green (0/0); EmittedIL 1413 pass/0 fail;
EditorTests AnyNewLine pass; DependencyManager nuget-roots test pass;
ilverify FCS net11.0 exact-matches baseline.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Support NotNullIfNotNullAttribute (#19977)

* Move SDL/TSA validation to 1ES templates after Arcade 11 upgrade (#20096)

Arcade 11 removed the SDL post-build scripts and the SDLValidationParameters parameter, breaking the official build. Move PoliCheck exclusions into the 1ES sdl: block and drop the obsolete post-build parameter and its variable group.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7df99ba6-98b9-4cab-898b-422577b9e6dc

* Compiled ToStrings under -reflectionfree for DUs and Records (#19976)

* Add a compiler intrinsic for the 'string' operator

Adds string_operator_info / mkCallStringOperator so generated code can call
Operators.string. These lines are duplicated by the interpolated-string PR
(#19971); kept identical there so a future merge resolves cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Generate a match-based ToString for unions under --reflectionfree

Under --reflectionfree the union ToString previously emitted nothing, so
DUs fell back to Object.ToString() (the namespace-qualified type name).
Instead generate a match over the cases that builds "CaseName(f0, f1, ...)"
using the 'string' operator on each field, via a TypedTree expression fed
to CodeGenMethodForExpr. This recurses naturally into nested unions and is
reflection-free. The default (sprintf "%+A") path is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Extract mkStringConcat helper for arity-dispatched String.Concat

The "concatenate a list of string exprs, picking the cheapest String.Concat
overload by arity" pattern was duplicated in CheckExpressions (interpolation
lowering) and the optimizer, and our new union ToString used the array
overload unconditionally. Extract mkStringConcat into TypedTreeOps.ExprOps
and route all three through it. This also lets single-field union cases emit
Concat3 instead of allocating a string[] (IlxGen runs after the optimizer, so
nothing else would collapse that array form).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix generated union ToString for generic unions

The match-based ToString body is a TypedTree expression codegen'd via
CodeGenMethodForExpr, but it was built with `eenv`, which lacks the tycon's
type parameters. For generic unions this produced wrong IL: the wrong case
branch (always the null-as-true-value case) or a NullReferenceException for
single-case unions. Use `eenvinner` (the per-tycon environment) so the
generic method body resolves its type parameters. The old sprintf path was
unaffected because it emits raw IL off the pre-built ilThisTy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Render union ToString fields like option (null -> "null")

To make a generated union ToString consistent with how option/list format
their contents (LanguagePrimitives.anyToStringShowingNull), format each field
as: if (box field) is non-null then 'string field' else "null". Previously a
null field rendered as "" (the 'string' operator's null behaviour). Generated
inline rather than calling anyToStringShowingNull, which is internal to
FSharp.Core and so not callable from user-compiled code.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Tidy reflection-free union ToString tests

Normalize union declarations to a leading '|', use System.Console.WriteLine
instead of printfn (the printf machinery is what these changes move away
from), and make the null-field test compare the union's rendering directly
against option's rather than asserting a fixed string.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add reflection-free ToString to Result and Choice

Result and Choice had no ToString override, so they fell back to the
compiler-generated sprintf "%+A" one, which uses reflection. Give them
hand-written overrides mirroring option/list (String.Concat +
anyToStringShowingNull), e.g. Ok 5 -> "Ok(5)", Choice1Of2 7 -> "Choice1Of2(7)".
This is reflection-free / AOT-friendly and consistent with option's "Some(x)"
rendering. Note: this changes the observable ToString of Result/Choice from
the "%A"-style "Ok 5" to "Ok(5)".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Generate a single-line ToString for records under --reflectionfree

Records previously fell back to Object.ToString() (the namespace-qualified
type name) under --reflectionfree. Generate "{ F1 = v1; F2 = v2 }" on a single
line (no line breaks, unlike sprintf "%+A"), with fields formatted like union
fields (null -> "null", otherwise via 'string'). Factor the shared field
formatter and ToString-method emission out of the union path. The default
(sprintf "%+A") path is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Update FSharp.Core surface-area baselines for Result/Choice ToString

Result and Choice`2..7 now declare an explicit ToString() override, so they
appear in the public surface area.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add release notes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Generate a single-line ToString for anonymous records under --reflectionfree

Drive anonymous-record ToString through the synthetic record tycon (already
built for equality/comparison) rather than sprintf "%A", so under
--reflectionfree it renders "{| Name = value; ... |}" on a single line.
GenRecordToStringMethod now takes open/close brace strings ("{ "/" }" for
records, "{| "/" |}" for anonymous records). The default (non-reflection-free)
codegen path is unchanged and still falls back to sprintf "%+A".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Test that a hand-written ToString override is kept under --reflectionfree

Addresses review feedback: generation is gated on `not (HasMember "ToString")`,
so a user-defined ToString on a union or record wins over the generated one.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Rename ToString generators for clarity

Addresses review feedback: distinguish the reflective sprintf path from the
structural one. GenPrintingMethod -> GenSprintfPrintingMethod (the sprintf "%+A"
ToString/get_Message), GenToStringMethodFromExpr -> EmitToStringMethodDef.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Restore tabular layout for string_operator_info in TcGlobals

Addresses review feedback: keep the column-aligned layout of the surrounding
intrinsic table. Also makes these two lines byte-identical to the same intrinsic
added by #19971, so a future merge resolves cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add reflection-free ToString tests for field shapes, structs, anon records and recursion

Covers DU field shapes (multiple fields vs a single tuple field), explicit
vs unnamed field names rendering identically, struct unions/records,
anonymous and struct anonymous records, and finite recursive/nesting types.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add EmittedIL tests for reflection-free record and union ToString

Locks in the IL emitted under --reflectionfree: each field is boxed and
rendered through Operators.ToString with a null guard, and the parts are
joined with String.Concat (array form for the record, 3-arg form for the
single-field union case). Nullary union cases return the bare case name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Generate reflection-free ToString in the augmentation phase

The structural ToString for --reflectionfree records and unions was built in
IlxGen, after the optimizer, so its per-field 'string' operator calls were
never inlined: each value-type field was boxed and rendered through the
generic Operators.ToString, behind a null guard that is dead for a value type.

Move the generation into the type-augmentation phase (alongside
Equals/GetHashCode/CompareTo) so the body flows through the optimizer. The
'string' operator is now specialised - a value-type field renders via a direct,
allocation-free invariant-culture ToString with no boxing and no null guard
(reference fields keep the guard so null still renders as "null"). The shared
body builders live in AugmentTypeDefinitions; anonymous record types are
synthesized too late for augmentation, so they keep generating in IlxGen but
reuse the same builder.

Output is unchanged; the EmittedIL baselines are updated to the leaner IL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Guard generated reflection-free ToString against deep-recursion overflow

The augmentation-generated structural ToString recurses into fields, so a deeply
nested value can exhaust the stack with an uncatchable StackOverflowException.
Emit RuntimeHelpers.EnsureSufficientExecutionStack() at method entry (as C# records
do in PrintMembers) so it throws a catchable InsufficientExecutionStackException
instead, when the runtime provides the method. The guard is skipped for types whose
every field is a flat primitive (integer/float/decimal/string/char/bool/unit/enum),
which cannot recurse.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Test the reflection-free ToString deep-recursion guard

A 1,000,000-deep value's generated ToString throws a catchable
InsufficientExecutionStackException rather than hard-crashing the process.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* revert ToString additions to fsharp.core types

* Remove stale FSharp.Core release note for the reverted Result/Choice ToString

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Fix code formatting in IlxGen.fs (dotnet fantomas)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* don't use quoted name

* int version of reflectionfree-printing doc

* doc tweaks

* Link release note to the printing doc and cover anonymous records

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test backticks

* Share the ToString recursion guard with anonymous records

The guard lived in MakeBindingsForToStringAugmentation, which anonymous
records bypass: they are synthesized too late for type augmentation and
reach mkRecdToString from IlxGen instead. Deep nesting overflowed the
stack rather than raising InsufficientExecutionStackException.

Move it into mkToStringRecursionGuard, applied inside mkRecdToString and
mkUnionToString, so every caller of the body builders gets it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add EmittedIL baselines for struct and anonymous record ToString

Struct records and unions read fields off the this pointer and switch on
the tag, and the anonymous record path is generated separately in IlxGen,
so each gets its own baseline.

The anonymous baseline omits the field reads: they name the anonymous
type, whose mangled name is not stable across compilations.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Fix empty anonymous record ToString rendering a doubled space

The open/close braces carry inner spaces ("{| " and " |}"); with no
fields they abut and render "{|  |}". Trim the leading space when the
field list is empty, matching %A's "{| |}".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* tidy comment

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Run ilverify via the tool manifest instead of a hard-coded cache path (#20101)

* Record spreads (#18927)

* Implement interpolated strings via String.Concat (#19971)

* [main] Source code updates from dotnet/dotnet (#20058)

* Backflow from https://github.com/dotnet/dotnet / 50dbab4 build 322464

Diff: https://github.com/dotnet/dotnet/compare/920a0d55f8d87a0423dd3a89555f70d9c9004584..50dbab4de210e882172b07934e9666313b7065f1

From: dotnet/dotnet@920a0d5
To: dotnet/dotnet@50dbab4

[[ commit created by automation ]]

* Update dependencies from build 322464
Updated Dependencies:
Microsoft.Build, Microsoft.Build.Framework, Microsoft.Build.Tasks.Core, Microsoft.Build.Utilities.Core (Version 18.10.0-1.26359.10 -> 18.10.0-preview-26357-08)
[[ commit created by automation ]]

* Update dependencies from build 322734
No dependency updates to commit
[[ commit created by automation ]]

* Update dependencies from build 322911
No dependency updates to commit
[[ commit created by automation ]]

* Update dependencies from build 323048
No dependency updates to commit
[[ commit created by automation ]]

* Fix NU1903 audit failures from updated transitive dependencies

The codeflow update to Microsoft.Build.* now transitively pulls
System.Security.Cryptography.Xml 10.0.8 (newly flagged by GHSA advisories,
patched in 10.0.10) on .NET, and Microsoft.CodeAnalysis.Test.Resources.Proprietary
-> NETStandard.Library 1.6.1 pulls vulnerable System.Net.Http 4.3.0 and
System.Text.RegularExpressions 4.3.0 on net472.

- Bump System.Security.Cryptography.Xml override to 10.0.10 (Version.Details).
- Add .NET-only Cryptography.Xml overrides in fsc/fsi/FSharp.Build.UnitTests
  (net472 excluded: no such transitive there and its deps conflict with
  System.ValueTuple). These cascade to Microsoft.FSharp.Compiler and FSharpSuite.Tests.
- Override the net472 System.Net.Http/System.Text.RegularExpressions facades to
  patched 4.3.4/4.3.1 in FSharp.Test.Utilities.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Pin MessagePack to patched 2.5.302 to fix NU1902/NU1903 audit

StreamJsonRpc 2.25.29 pulls MessagePack transitively; some restore
environments resolve the vulnerable 2.5.198 (< 2.5.301 patched line),
tripping NuGetAudit warnings-as-errors in FSharp.Compiler.LanguageServer.Tests.
Add an explicit direct reference at 2.5.302 (StreamJsonRpc's own minimum,
already patched) so the resolved version is deterministic everywhere.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix malformed Version.Details.xml (duplicate closing Dependency tag)

A merge conflict resolution left a stray </Dependency> closing tag after
Microsoft.Build.Utilities.Core, making the XML invalid and failing the
Maestro Version.Details.props Validation and Codeflow verification checks.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>

* Secure release-note checks for fork pull requests (#20081)

* Secure release-note checks for fork pull requests

* Address release-note workflow review feedback

* Update test project to net11 (#20104)

* Update test project to net11

Internal CI was failing since the move to net11 because restoring this
test project had to suddenly be done via network call to nuget.org

* Update target framework and PDB path in tests

* Update dependencies from https://github.com/dotnet/arcade build 20260803.2
On relative base path root
Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26379.2 -> To Version 10.0.0-beta.26403.2

* Move to Roslyn's unified ExternalAccess library (#20099)

* LexFilter: drop non-strict mode (#20106)

* Enable Central Package Management with transitive pinning (#20084)

* Implement direct delegates (#19993)

* Fix check_release_notes 403 by restoring pull-requests: write and making the comment non-fatal (#20198)

check_release_notes runs via pull_request_target, so GitHub executes the workflow from the default branch (main). Creating the informational PR comment requires pull-requests: write, but #20081 reduced the token to read, turning the check red with HTTP 403 on any PR that had to create (not update) the comment - e.g. Maestro/darc PR #20133. Restore pull-requests: write so the comment posts, and guard the comment step with continue-on-error plus try/catch so posting can never fail the release-notes verdict. Supersedes #20200.

* Restore NuGetRepack UsingTask workaround for Arcade 10 in Microsoft.FSharp.Compiler.fsproj

The merge from main overwrote this project with main's Arcade-11 form, which
relies on the Microsoft.DotNet.NuGetRepack.Tasks package auto-importing the
UpdatePackageVersionTask UsingTask. On release/10.0.4xx (Arcade 10) that package
does not ship the build props, so the task must be declared explicitly. Without
it every packaging build leg failed with MSB4036 (task not found). Restores the
explicit UsingTask (tracked by #19557) while keeping the CPM-managed
PackageReference (no Version attribute).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update dependencies from https://github.com/dotnet/arcade build 20260804.3
On relative base path root
Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26379.2 -> To Version 10.0.0-beta.26404.3

---------

Co-authored-by: Nat Elkins <nat@nelknet.com>
Co-authored-by: Tomas Grosup <Tomas.Grosup@gmail.com>
Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: dotnet bot <dotnet-bot@dotnetfoundation.org>
Co-authored-by: T-Gro <15220165+T-Gro@users.noreply.github.com>
Co-authored-by: Eugene Auduchinok <eugene.auduchinok@jetbrains.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: kerams <kerams@users.noreply.github.com>
Co-authored-by: Adam Boniecki <20281641+abonie@users.noreply.github.com>
Co-authored-by: Charles Roddie <charles.roddie@cantab.net>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Brian Rourke Boll <brianrourkeboll@users.noreply.github.com>
Co-authored-by: Charles Roddie <charles.roddie@summatic.co.uk>
Co-authored-by: Joey Robichaud <joseph.robichaud@microsoft.com>
Copilot-Session: 7df99ba6-98b9-4cab-898b-422577b9e6dc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚠️ Affects-Build-Infra Tooling check: PR touches build infrastructure ⚠️ Affects-Restore Tooling check: PR touches NuGet packages or feeds AI-Tooling-Check-Bypassed Tooling check: non-fork PR, not diff-analyzed NO_RELEASE_NOTES Label for pull requests which signals, that user opted-out of providing release notes

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants